import unittest

from Base import *

class TestBaseMath(unittest.TestCase):

    def testGCD(self):
        self.assertEqual(GCD(3, 4), 1)
        self.assertEqual(GCD(3, 6), 3)
        self.assertEqual(GCD(0, 1), 1)
        self.assertEqual(GCD(1, 0), 1)
        self.assertEqual(GCD(-2, 4), 2)

    def testBezoutIdentity(self):
        self.assertEqual(BezoutIdentity(120, 23), (1, -9, 47))
        self.assertEqual(GCD(120, 23), 1)

    def testPrimality(self):
        self.assertTrue(not IsPrime(1))
        self.assertTrue(IsPrime(2))
        self.assertTrue(IsPrime(89))
        self.assertTrue(not IsPrime(91))

        self.assertEqual(CoprimeSet(4), [1, 3])
        self.assertEqual(CoprimeSet(1), [1])
        self.assertEqual(CoprimeSet(2), [1])
        self.assertEqual(len(CoprimeSet(89)), 88)

from Group import MultiModGroup

class TestMultiModGroup(unittest.TestCase):

    def testAddition(self):
        mod5 = MultiModGroup(5)
        self.assertEqual(mod5.Add(2, 3), 0)
        self.assertEqual(mod5.Subtract(7, 2), 0)

    def testMultiplication(self):
        mod5 = MultiModGroup(5)
        self.assertEqual(mod5.Multiply(2, 3), 1)
        self.assertEqual(mod5.Inverse(1), 1)
        self.assertEqual(mod5.Inverse(2), 3)

        mod4 = MultiModGroup(4)
        self.assertRaises(AssertionError, mod4.Inverse, 2)
        self.assertEqual(mod4.Inverse(3), 3)

    def testOrder(self):
        mod5 = MultiModGroup(5)
        self.assertEqual(mod5.Order(), 4)
        self.assertEqual(mod5.ElementOrder(1), 1)
        self.assertEqual(mod5.ElementOrder(2), 4)

        mod6 = MultiModGroup(6)
        self.assertEqual(mod6.Order(), 2)
        self.assertEqual(mod6.ElementOrder(5), 2)

        mod15 = MultiModGroup(15)
        self.assertEqual(mod15.ElementOrder(7), 4)
        self.assertEqual(mod15.ElementOrder(11), 2)
        self.assertEqual(mod15.ElementOrder(-4), 2)

    def testCyclic(self):
        mod5 = MultiModGroup(5)
        self.assertEqual(mod5.items, [1, 2, 3, 4])
        self.assertEqual(mod5.IsCyclic(), (True, [2, 3]))
        self.assertEqual(mod5.Identity(), 1)

        mod15 = MultiModGroup(15)
        self.assertEqual(mod15.items, [1, 2, 4, 7, 8, 11, 13, 14])
        self.assertEqual(mod15.IsCyclic(), (False, []))
        self.assertEqual(mod15.Identity(), 1)

    def testSubgroup(self):
        mod20 = MultiModGroup(20, (4, 8, 12, 16))
        self.assertEqual(mod20.IsCyclic(), (True, [8, 12]))
        self.assertEqual(mod20.Identity(), 16)

        mod84 = MultiModGroup(84, [7, 35, 49, 77])
        self.assertEqual(mod84.Identity(), 49)
        self.assertEqual(mod84.IsCyclic(), (False, []))

from Vector import *

class TestVector(unittest.TestCase):
    def testBrief(self):
        self.assertEqual(Vector(), Vector(0.0, 0.0, 0.0))
        self.assertTrue(Vector() == Vector())
        self.assertTrue(not Vector() != Vector())
        self.assertNotEqual(Vector(), Vector(0.0001, 0.0, 0.0))
        self.assertEqual(Vector(1.0) + Vector(-1), Vector())
        self.assertEqual(Vector(1.0) - Vector(1), Vector())
        self.assertEqual(Vector(1.0), -Vector(-1.0))

        self.assertEqual(Dot(Vector(1.0), Vector(-1)), -1)
        self.assertEqual(Cross(Vector(1), Vector(0, 1)), Vector(0, 0, 1))

        self.assertEqual(Vector(2).Length(), 2)
        self.assertEqual(Vector(2).LengthSquared(), 4)
        self.assertEqual(Vector(2).Normalize(), Vector(1))

if __name__ == "__main__":
    all_tests = unittest.TestSuite((
        unittest.makeSuite(TestBaseMath),
        unittest.makeSuite(TestMultiModGroup),
        unittest.makeSuite(TestVector)))

    runner = unittest.TextTestRunner()
    runner.run(all_tests)
